package com.acme.bankapp.service.bank;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.acme.bankapp.domain.bank.Account;
import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.Client;

/**
 * 
 * @author Anton Kotov
 * 
 */
public class BankReport {
    /**
     * 
     * @param bank
     * @return counts of bank's clients
     */
    public static int getNbOfCustomers(final Bank bank) {
	return bank.getClients().size();
    }

    /**
     * 
     * @param bank
     * @return total counts of bank client's accounts
     */
    public static int getNbOfAccounts(final Bank bank) {
	int nAccounts = 0;

	for (Client client : bank.getClients()) {
	    nAccounts += client.getAccounts().size();
	}

	return nAccounts;
    }

    /**
     * 
     * @param bank
     * @return list of all bank client's accounts ordered by balance
     */
    public static List<Account> getAccountsSortedBySum(final Bank bank) {
	List<Account> list = new ArrayList<>();

	for (Client client : bank.getClients()) {
	    for (Account account : client.getAccounts()) {
		list.add(account);
	    }
	}

	Collections.sort(list, new Comparator<Account>() {
	    public int compare(Account a1, Account a2) {
		double difference = a1.getBalance() - a2.getBalance();
		if (difference > 0.0) {
		    return 1;
		} else if (difference < 0.0) {
		    return -1;
		} else {
		    return 0;
		}
	    }
	});

	return list;
    }

    /**
     * 
     * @param bank
     * @return total credit of checking accounts
     */
    public static double getBankCredit(final Bank bank) {
	double credit = 0.0;

	for (Client client : bank.getClients()) {
	    for (Account account : client.getAccounts()) {
		credit -= Math.min(0.0, account.getBalance());
	    }
	}

	return credit;
    }

    /**
     * 
     * @param bank
     * @return map: client -> set of accounts
     */
    public static Map<Client, Set<Account>> getCustomerAccount(final Bank bank) {
	Map<Client, Set<Account>> map = new HashMap<Client, Set<Account>>();

	for (Client client : bank.getClients()) {
	    map.put(client, client.getAccounts());
	}

	return map;
    }

}
